package com.google.code.stalkernet.example.ui.action;

import java.awt.event.ActionEvent;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collection;

import javax.swing.AbstractAction;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.google.code.stalkernet.example.ui.ServerTableModel;
import com.google.code.stalkernet.reactor.Reactor;
import com.google.code.stalkernet.server.Server;

/**
 * Action that removes selected {@link SocketAddress}es from {@link Server}.
 *
 * @author Mikhail Vladimirov
 */
public class RemoveServerSocketAddressesAction
    extends AbstractAction
{
    private final MyListSelectionListener myListSelectionListener =
        new MyListSelectionListener ();

    private final Reactor reactor;
    private final ListSelectionModel listSelectionModel;
    private final ServerTableModel serverTableModel;
    private final Server server;

    /**
     * Create new remove server socket address action that uses given
     * {@link ListSelectionModel}, obtains selected {@link SocketAddress}es from
     * given {@link ServerTableModel} and removes them from given{@link Server}.
     *
     * @param listSelectionModel {@link ListSelectionModel} to use
     * @param serverTableModel {@link ServerTableModel} to get selected
     *        {@link SocketAddress}es from
     * @param server {@link Server} to remove selected {@link SocketAddress}es
     *        from
     */
    public RemoveServerSocketAddressesAction (
        Reactor reactor,
        ListSelectionModel listSelectionModel,
        ServerTableModel serverTableModel,
        Server server)
    {
        super ("Remove Server Socket Addresses");

        if (reactor == null)
            throw new IllegalArgumentException ("Reactor is null");

        if (listSelectionModel == null)
            throw new IllegalArgumentException ("List selection model is null");

        if (serverTableModel == null)
            throw new IllegalArgumentException ("Server table model is null");

        if (server == null)
            throw new IllegalArgumentException ("Server is null");

        this.reactor = reactor;
        this.listSelectionModel = listSelectionModel;
        this.serverTableModel = serverTableModel;
        this.server = server;

        listSelectionModel.addListSelectionListener (myListSelectionListener);

        updateState ();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void actionPerformed (ActionEvent e)
    {
        if (!listSelectionModel.isSelectionEmpty ())
        {
            int min = listSelectionModel.getMinSelectionIndex ();
            int max = listSelectionModel.getMaxSelectionIndex ();

            final Collection <SocketAddress> socketAddresses =
                new ArrayList <> ();
            for (int i = min; i <= max; i++)
            {
                if (listSelectionModel.isSelectedIndex (i))
                    socketAddresses.add (
                        serverTableModel.getSocketAddressAt (i));
            }

            reactor.invoke (
                new Runnable()
                {
                    @Override
                    public void run ()
                    {
                        for (SocketAddress socketAddress: socketAddresses)
                            server.removeSocketAddress (socketAddress);
                    }
                });
        }
    }

    private void updateState ()
    {
        setEnabled (!listSelectionModel.isSelectionEmpty ());
    }

    private class MyListSelectionListener implements ListSelectionListener
    {
        @Override
        public void valueChanged (ListSelectionEvent e)
        {
            updateState ();
        }
    }
}
